<?php

/**
 * @desc Application interface translation. 
 *
 */
abstract class Kernel_i18n 
{
    
    /**
    * @desc Default language. 
    * 
    */
    const LANGUAGE = 'en';

    /**
     * @desc Current language name. 
     *
     * @var string
     */
    static private $_lang;

    /**
     * @desc Locale implementation for current language. 
     *
     * @var Kernel_i18n_Abstract
     */
    static private $_locale;

    /**
     * @desc Terms translations. 
     *
     * @var array
     */
    static private $_values = array();
    
    /**
     * @desc Array of imported packages in order not to load twice. 
     *
     * @var array
     */
    static private $_imported = array();

    
    
    /**
     * @desc Set interface language if specified and return previous value. 
     *
     * @param   string  $lang
     * @return  string
     */
    static public function lang($lang = null) 
    {
        $_lang = self::$_lang;
        if (!is_null($lang)) {
            self::$_lang = $lang;
            // in case of language changing erase previously imported terms
            self::$_values = array();
            
            try {
                // try to load current language locale
                self::_locale($lang);
            } catch (Zend_Exception $e) {
                // otherwise load default one
                self::_locale(self::LANGUAGE);
            }
        }
        return $_lang;
    }

    /**
     * @desc Return specified term translation.
     *
     * @param   string  $phrase
     * @return  string
     */
    static public function get($phrase) 
    {
        // separate arguments from term
        $args = array_slice(func_get_args(), 1);
        return null !== ($value = @self::$_values[$phrase])
            // if arguments are passed
            ? (count($args) > 0
                // format according to the template
                ? (!is_array($value)
                    ? vsprintf($value, $args)
                    : self::$_locale->plural($value, reset($args)))
                // or simply get term translation
                : $value)
            // if nothing helped try to present term in normal way
            : utf8_ucfirst(utf8_lowercase(str_replace('_', ' ', $phrase)));
    }

    /**
     * @desc Define whether translation for the specified term exists. Can be 
     * useful for replacing standart translations with customized. 
     *
     * @param   string  $phrase
     * @return  boolean
     */
    static public function exists($phrase) 
    {
        return isset(self::$_values[$phrase]);
    }

    /**
     * @desc Load terms translations for the specified package(s). 
     *
     * @param   string  $package1 [, string $package2, ...]
     */
    static public function import() 
    {
        $packages = func_get_args();
        
        // :KLUDGE: dV 20081124: 
        // remember source language
        $_lang = self::$_lang;
        $interface_lang = Backend_Filter_Structure::get(Backend_Filter_Structure::LANG_INTERFACE);
        // if isset interface language and its different from system
        // change language to import terms
        if (!is_null($interface_lang) && $interface_lang != $_lang) {
            self::$_lang = $interface_lang;
        }
        
        self::_fromFile($packages);
        self::_fromDB($packages);
        
        // set back initial language value
        self::$_lang = $_lang;
    }
    
    /**
    * @desc Search for language files. 
    * 
    * @param array $packages
    */
    static private function _fromFile($packages) 
    {
        foreach ($packages as $package) {
            if (!in_array($package, self::$_imported)) 
            {
                foreach (array(KERNEL_REPOSITORY, PROJECT_REPOSITORY) as $dir) {
                    $path = $dir  . DIRECTORY_SEPARATOR . $package . DIRECTORY_SEPARATOR . 'Lang';
                    try {
                        self::_import(Zend_Loader::loadFile(self::$_lang . '.php', $path));
                    } catch (Zend_Exception $e) {}
                }
            }
            self::$_imported[] = $package;
        }
    }
    
    /**
    * @desc Search for language terms in the database. 
    * 
    * @param array $packages
    */
    static private function _fromDB($packages) 
    {
        // always load terms from specified packages from DB nevetherless 
        // terms are loaded from files
        
        static $cach;
        
        if (is_null($cach)) {
            try {
                $query = '
                    SELECT 
                           `p`.`package`, 
                           `l`.`term`, 
                           `l`.`translation` 
                      FROM 
                           `system_packages` `p`, `__' . self::$_lang . '` `l`
                     WHERE 
                           `l`.`package` = `p`.`id`
                    ';
                $values = database::fetchAll($query);
                while($row = array_shift($values)) {
                    $cach[$row['package']][$row['term']] = $row['translation'];
                }
            } catch (Kernel_Db_Exception $e) {
                $cach = array();
            }
        }
        
        // return only those which present guaranteed
        foreach (array_intersect(array_keys((array)$cach), $packages) as $package) {
            self::_import($cach[$package]);
            self::$_imported[] = $package;
        }
    }

    /**
     * @desc Import array of language terms.
     *
     * @param   array   $phrases
     */
    static private function _import($phrases) 
    {
        self::$_values = array_merge(self::$_values, $phrases);
    }
    
    /**
    * @desc Load language locale. 
    * 
    * @param string
    */
    static private function _locale($lang) 
    {
        self::$_locale = Zend_Loader::loadClass('Kernel_i18n_' . ucfirst($lang));
    }
    
}

/**
 * @desc Shortcut for Kernel_i18n::get(). Return specified term translation. 
 *
 * @param   string  $phrase [, mixed $param1, …]
 * @return  string
 */
function __() 
{
    $args = func_get_args();
    return call_user_func_array(array('Kernel_i18n', 'get'), $args);
}

/**
 * @desc Shortcut for Kernel_i18n::lang(). 
 * Set interface language if specified and return previous value. 
 *
 * @param   string  $lang
 * @return  string
 */
function __lang($lang = null) 
{
    return Kernel_i18n::lang($lang);
}





/**
* @desc In the very beginning set default language. 
* 
*/
Kernel_i18n::lang(defined('LANGUAGE') ? constant('LANGUAGE') : Kernel_i18n::LANGUAGE);